// 条件类型 extends 约束  经常和条件类型一起使用
type ResStatusMessage<T> = T extends 200 | 201 | 204 | 206 ? 'success' : 'fail'

// 字面类型
type IMessage = ResStatusMessage<200> 
//对于联合类型而言子类型是其中的任何一个
// 交叉后的结果 就是 交叉前的某个类型中的子类型

type Conditional<T,U> = T extends U ? true : false

type R1 = Conditional<'js',string>

type FromatReturnValue<T> = T extends string ? string : T extends number ? number: never
function sum<T extends string | number>(a:T,b:T):FromatReturnValue<T>{
    return a + (b as any) //T 和T 不能做运算  只能将b断言
}
let r = sum(1,2)
// extends 父子关系 类型登记
type T1 = never extends '123' ? true : false //子类型可以赋予给父类型
//1） never 和 字面量的关系
let a:number = (function():never{
    throw new Error()
})() 
// 2）字面量类型是基础类型的子类型
type T2 = 123 extends number ? true : false
type T3 = 'abc' extends string ? true : false
// 3)字面量类型 和基础类型的关系
// 基础类型是包装类型的子类型
type T4 = string extends String ? true : false
// 4）any:所有类型都是any和unknwn的子类型
type T5 = Object extends any ? true :false
// any unkown 顶端类型
type T6 = any extends unknown ? true :false

type T7 = any extends 1 ? true : false //any可以看做是1+ 其他类型  内置有分发的机制 直接取的是联合类型

interface Fish{
    name:'鱼'
}
interface Water{
    type:'水'
}
interface Bird{
    name:'鸟'
}
interface Sky{
    type:'太空'
}
type SelectType<T> = T extends Fish ? Water : Sky
// Bird->Fish->Sky
// Fish->Fish->Water
// Sky | Water
type T8 = SelectType<Bird | Fish>
type T9 = Bird | Fish extends Fish ? Water : Sky

// 分发机制：
// 1）通过泛型传入的方式来比较的时候会出现分发
// 2）类型需要是联合类型
// 3）类型完全的裸露出来

// 知道了分发机制的产生原因  在开发总就需要避免
// 缺点：1）判断谁是谁的子类型时，就会发生异常 

// 解决分发的第二种方法
type NoDistruble<T> = T & {} //包一层 不分发
type UnionAssets<T,U> = T extends U ? true : false
// 解决分发的第一种方法
// type UnionAssets<T,U> = [T] extends [U] ? true : false

type T10 = UnionAssets<1 | 2, 1 | 2 | 3>

type T11 = UnionAssets<1 | 2 | 3, 1 | 2>


// 如何判断两个类型完全相等：
type NoDistrubute<T> = T & {}
type IsEqual<T,U,Success,Fail> = NoDistrubute<T> extends U ? NoDistrubute<U> extends T ?Success : Fail : Fail

// 有功能的类型用type 描述性的用interfase
type T12 = IsEqual<1|2,1|2,true,false>

// never 做比较的时候，也会有分发问题
//  - any 默认分发
//  - never 默认只有通过泛型传递的时候会返回never  不分发就正常

type isNever<T> = T extends '123' ? true :false
// type isNever<T> = NoDistruble<T> extends '123' ? true :false

type T13 = isNever<never>


// 父子类型关系  如何判断两个类型的父子关系 extends用法 （分发带来的问题）


// 内置的条件类型 Extract Exclude NonNullable


// 获取两个联合类型的交集
type Extract<T,U> =T extends U ? T : never  //string | number | never
type ExtractResult = Extract<string | number,string | number | boolean>
type Exclude<T,U> =T extends U ? never : T  //never | never | boolean

type ExcludeResult = Exclude<string | number | boolean,string | number >

// 补集？ 含义就是互补的，差集+子类的关系

type Complement<T,U extends T> = T extends U ? never : T
type ComplementResult  =  Complement<string|number|boolean,string>

let ele = document.getElementById('root')


// type NonNullable<T> = T extends null | undefined ? never : T 
type NonNullable<T> = T & {}
type EleElement = NonNullable<typeof ele> 


// infer类型推断
export{}